package cn.wolfcode.exception;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.wolfcode.domain.SystemLog;
import cn.wolfcode.service.ISystemLogService;
import cn.wolfcode.util.*;
import com.alibaba.fastjson.JSON;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;

//在 该类贴@ControllerAdvice注解后，代表改类是对控制器进行增强的
@ControllerAdvice
public class MyControllerAdvice {

    @Autowired
    private ISystemLogService systemLogService;

    /**
     * @ExceptionHandler:代表的是该方法是用于处理某种异常
     */
    /**
     * 控制器中某个方法已经异常捕捉了，就不会进入控制器增强了,所以我们做了统一异常处理，就需要把controller,service中捕捉异常代码的直接处理
     */
    @ExceptionHandler(RuntimeException.class)
    public String handler(RuntimeException e, HttpServletResponse response, HandlerMethod method){
        //必须要在控制台打印异常信息
        e.printStackTrace();
        //需要根据前端请求的方式来响应不同的结果
        //如果原本是需要返回视图的就可以返回error页面
        //如果原本需要返回JsonResult,现在也要返回JsonResult
        //判断控制器的方法上是否有Responsebody注解，有的话就是返回视图，取反就是返回页面

        TimeInterval timer = DateUtil.timer();
        timer.start();
        if (!(method.hasMethodAnnotation(ResponseBody.class))){
            if (method.hasMethodAnnotation(RequiredPermission.class)){
                SystemLog systemLog= LogManagerSetUtil.getLogManager(timer.interval()
                        ,(RequiredPermission)method.getMethodAnnotation(RequiredPermission.class),false,e);
                systemLogService.save(systemLog);
            }
            //如果方法没有贴responsebody ,则返回 视图
            return "common/error";

        }else {
            JsonResult jsonResult = new JsonResult(false, "系统异常，请联系管理员！");
            try {
                //用原生的response,request一般都需要设置字符请求格式
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().println(JSON.toJSONString(jsonResult));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    //专门处理我们自定义的逻辑异常的:比如登陆的时候密码为空，用户名为空，用户名或者密码错误
    @ExceptionHandler(LogicException.class)
    @ResponseBody
    public JsonResult handler2(Exception e){
        return new JsonResult(false,e.getMessage());
    }


}
